module pulse_cnt (
    input             sys_clk,
    input             rst_n,
    input             sig_in_i,
    input             cnt_ena_i,
    output reg [11:0] bcdcnt_o,
    output reg        overflow_o
);

  wire        sig_in_s;

  reg  [11:0] cnt_reg;
  wire [11:0] cnt_inc;
  wire        cnt_cout;

  reg         sig_del;
  reg         ena_del;

  assign sig_in_s = sig_in_i;

  bcd_inc cnt_inc_inst (
      .din (cnt_reg),
      .dout(cnt_inc),
      .cout(cnt_cout)
  );

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      sig_del <= 1'b1;
    end else if (~cnt_ena_i) begin
      sig_del <= 1'b1;
    end else begin
      sig_del <= sig_in_s;
    end
  end

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      cnt_reg <= 0;
    end else if (~cnt_ena_i) begin
      cnt_reg <= 0;
    end else if ((~sig_del & sig_in_s)) begin  // detect rising edge
      if (~cnt_cout) begin
        cnt_reg <= cnt_inc;
      end
    end
  end

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      ena_del <= 1'b0;
    end else begin
      ena_del <= cnt_ena_i;
    end
  end

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      bcdcnt_o   <= 0;
      overflow_o <= 1'b0;
    end else if (cnt_cout | (ena_del & ~cnt_ena_i)) begin
      bcdcnt_o   <= cnt_reg;
      overflow_o <= cnt_cout;
    end
  end

endmodule
